/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aptech.eproject.logictics.dao.thinh.ManageTrip;

import aptech.eproject.logictics.db.*;
import java.util.*;
import javax.annotation.*;
import javax.ejb.*;
import javax.persistence.*;
import org.jboss.annotation.ejb.Clustered;
import org.jboss.annotation.ejb.cache.simple.CacheConfig;

/**
 *
 * @author HOANGTHINH
 */
@Stateful(name = "stateful/AddTripService")
@CacheConfig(maxSize=5000,idleTimeoutSeconds=300,removalTimeoutSeconds=18000)
@TransactionManagement(value = TransactionManagementType.CONTAINER)
public class AddTripService implements AddTripRemote {

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    //dictPackageOfTrip store Package ID and status of its 0: default ,1 :add to trip , 2: remove from trip
    protected static Dictionary<Integer, Integer> dictPackageOfTrip;
    //dictPackageOfTrip store route ID and status of its 0: default ,1 :add  to trip , 2: remove from trip
    protected static Dictionary<String, Integer> dictRouteOfTrip;
    protected static String vehicleId;
    @Resource
    protected SessionContext context;
    @PersistenceContext(name = "LogicticsService")
    protected EntityManager em;

    /**
     * Init information of session bean
     * init dictPackageOfTrip store information about current package of trip
     * init dictRouteOfTrip store information about current route of trip
     */
    @PostActivate
    @PostConstruct
    public void initTripService() {
        dictPackageOfTrip = new Hashtable<Integer, Integer>();
        dictRouteOfTrip = new Hashtable<String, Integer>();
        vehicleId = null;
    }

    /**
     * get information about current vehicle of branch
     * @param branchId - Integer type
     * @return
     *      list with each element of its have type object v.vehicleId . 
     */
    public List listVehicleOfBranch(int branchId) {
        try {
            Query query = em.createQuery("SELECT v.vehicleId FROM Vehicle v WHERE v.branch.branchId = ?1 AND v.status=?2");
            query.setParameter(1, branchId);
            query.setParameter(2, VehicleStatus.Free);
            return query.getResultList();
        } catch (Exception e) {
            System.err.println("cannot get list vehicle of branch!!!");
            e.printStackTrace();
            return null;
        }

    }

    /**
     * call after choice vehicle from combo box. Use to save vehicle ID to session bean
     * @param vehicleId
     */
    public void saveVehicle(String vehicleId) {
        this.vehicleId = vehicleId;
    }

    /**
     * return weight limit of truck based on vehicl ID
     * @param vehicleId - String type
     * @return
     *      weight limit of vehicle
     */
    public int getWeightLimit(String vehicleId) {
        try {
            Vehicle v = em.find(Vehicle.class, vehicleId);
            return v.getWeightLimit();
        } catch (NullPointerException npe) {
            System.err.println("cannot get information about vehicle");
            return 0;
        } catch (Exception e) {
            System.err.println("Unknown error");
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Use this method . When user click close button on dialog
     */
    @PreDestroy
    @PrePassivate
    public void cancelTripService() {
        dictPackageOfTrip = null;
        dictRouteOfTrip = null;
        vehicleId = "";
    }

    /**
     * Get list all trip finished in all branch . Load when Trip Finished check box is checked
     * @return
     *      List element with element is object type trip
     */
    public List getListTripFinished() {
        try {
            Query query = em.createQuery("SELECT t FROM Trip t WHERE t.isFinished = 'True' AND t.isDeleted='False'");
            return query.getResultList();
        } catch (IllegalArgumentException iae) {
            System.err.println("Invalid query");
            return null;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("error : " + ex.getMessage());
            return null;
        }
    }

    /**
     * Get list all trip in all branch. Load when Show All check box is checked
     * @return
     *      List element with element is object type trip
     */
    public List getListTrip() {
        try {
            Query query = em.createQuery("SELECT t FROM Trip t WHERE  t.isDeleted='False'");
            return query.getResultList();
        } catch (IllegalArgumentException iae) {
            System.err.println("Invalid query");
            return null;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("error : " + ex.getMessage());
            return null;
        }
    }

    /**
     * Use to test if this trip is this branch manage. 
     * Call at time delete  trip or use to disable record what trip is not belong to this branch
     * @param branchId
     * @return
     *      true : The branch manage trip 
     *      false: the trip is own by other branch
     */
    public boolean isTripOfBranch(int tripId, int branchId) {
        try {
            Trip trip = em.find(Trip.class, tripId);
            vehicleId = trip.getVehicle().getVehicleId();
            Query query = em.createQuery("SELECT b FROM Vehicle v JOIN v.branch b WHERE v.vehicleId= ?1");
            query.setParameter(1, vehicleId);
            Branch b = (Branch) query.getSingleResult();
            if (b.getBranchId() != branchId) {
                return false;
            } else {
                return true;
            }
        } catch (ClassCastException cce) {
            System.err.println("Invalid cast type ");
            return false;
        } catch (IllegalArgumentException iae) {
            System.err.println("Invalid query");
            return false;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("error : " + ex.getMessage());
            return false;
        }
    }

    /**
     * get information about next branch based on current branchId.
     * Call this when click Add More Branch link
     * @param branchId - Integer type
     * @return
     *      return list next branch based on current branch id parameter
     *      Each element of list have two object
     *          * one object type branch
     *          * one object type integer
     */
    public List getListNextBranch(int branchId) {
        try {
            Query query = em.createQuery("SELECT r.routeId,r.toBranch FROM Route r WHERE r.fromBranch.branchId = ?1");
            query.setParameter(1, branchId);
            return query.getResultList();
        } catch (IllegalArgumentException iae) {
            System.err.println("Invalid query");
            return null;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("error : " + ex.getMessage());
            return null;
        }
    }

    /**
     * Call this method when click button Add Route To Trip
     * add list of route to trip.
     * @param lstRouteAddInTrip - List Type
     * @return
     *      List route is cannot add in trip . If list is empty Add all route successful
     */
    public List addRouteToTrip(List<String> lstRouteAddInTrip) {
        List routeAlreadyInTrip = new ArrayList();
        try {
            for (int i = 0; i < lstRouteAddInTrip.size(); i++) {
            String routeId = lstRouteAddInTrip.get(i);
           // System.out.println("Adding Route In Trip : "+routeId);
            try {
                if (dictRouteOfTrip.get(routeId) != null) {
                int status = dictRouteOfTrip.get(routeId);
                    if (status == 2) {
                        dictRouteOfTrip.put(routeId, 1);
                      //  System.out.println("This route is already add in trip with status is remove");
                    } else {
                        routeAlreadyInTrip.add(routeId);
                    }
                } else {
                    dictRouteOfTrip.put(routeId, 1);
                }
            } catch (NullPointerException npe) {
                dictRouteOfTrip.put(routeId, 1);
            }
        }

        } catch (Exception e) {
            System.out.println("Cannot Adding Route!!!!");
        }
          int routeAdd=0;
          int routeRemove=0;
           Enumeration key=dictRouteOfTrip.keys();
          // System.out.println("Route: ");
            while (key.hasMoreElements()) {
                String routeId = (String) key.nextElement();

                if(dictRouteOfTrip.get(routeId)==2)
                    routeRemove++;
                else
                {
                    routeAdd++;
                }
            }
       // System.out.println("Number Of Route Add: "+routeAdd+"\n Number Of Route Remove : "+routeRemove);
        return routeAlreadyInTrip;
    }

    /**
     * Call this method when click button Remove Route From Trip
     * remove list of route from trip.
     * @param lstRouteAddInTrip - List Type
     * @return
     *      List route is invalid to remove from trip . If list is empty Remove All route  successful
     */
    public List removeRouteFromTrip(List<String> lstRouteRemoveFromTrip) {
        List invalidRoutes = new ArrayList();
        try {
        for (int i = 0; i < lstRouteRemoveFromTrip.size(); i++) {
            String routeId = lstRouteRemoveFromTrip.get(i);
           // System.out.println("Removing Route :"+routeId);
            if (dictRouteOfTrip.get(routeId) != null) {
                int status = dictRouteOfTrip.get(routeId);
               // System.out.println(status);
                if (status == 2) {
                  // System.out.println("Cannot remove route " + routeId + " which is already remove from trip !");
                    invalidRoutes.add(routeId);
                } else {
                    dictRouteOfTrip.put(routeId, 2);
                }
            } else {
              // System.out.println("Cannot remove route " + routeId + " which is already remove from trip !");
                invalidRoutes.add(routeId);
            }
        }
         } catch (Exception e) {
            System.out.println("Cannot Removing Route!!!!");
        }
        return invalidRoutes;
    }

    /**
     * Use to whether if total weight of current package in trip is reach weight limit of vehicle
     * @return
     *   the double type describe weight which trip can be transport
     */
    public double isReachWeightLimit() {
        try {
            double totalWeight = 0;
            int weightLimit = getWeightLimit(vehicleId);
            Enumeration<Integer> packageIds = dictPackageOfTrip.keys();
            while (packageIds.hasMoreElements()) {
                Integer packageId = packageIds.nextElement();
                int status = dictPackageOfTrip.get(packageId);
                if (status != 2) {
                    totalWeight += getWeightOfPackage(packageId);
                }
            }
            return weightLimit - totalWeight;
        } catch (NullPointerException npe) {
            System.err.println("Cannot get weight limit if vehicle Id is null");
            return -1;
        }
    }

    /**
     * return weight of specified package
     * @param packageId
     * @return
     */
    private Double getWeightOfPackage(int packageId) {
        try {
            aptech.eproject.logictics.db.Package p = em.find(aptech.eproject.logictics.db.Package.class, packageId);
            return p.getWeight();
        } catch (NullPointerException e) {
            System.err.println("cannot find package information");
            return 0.0;
        }
    }

    /**
     * This method check each package had desBranch suitable with desBranch of what route in list of route
     *
     * @param lstPackageAddInTrip
     * @return
     *     dictInvalidPackage: list of package is not suitable to add in trip
     *     key : package Id
     *     value: status describe why cannot add package
     *          0: package cannot add because have weight greater than weight left of trip
     *          1: package not have suitable destination branch with destination branch of each route in trip
     */
    public Dictionary addPackageInTrip(List lstPackageAddInTrip,Dictionary<Integer, Integer> invalidPackages) {
         Dictionary<Integer, Integer> dictInvalidPackage = invalidPackages;
         try
         {
             for (int i = 0; i < lstPackageAddInTrip.size(); i++) {
            Integer packageId;
            if(lstPackageAddInTrip.get(i)instanceof  aptech.eproject.logictics.db.Package)
            {
                aptech.eproject.logictics.db.Package p=
                        (aptech.eproject.logictics.db.Package) lstPackageAddInTrip.get(i);
                packageId=p.getPackageId();
            }
            else packageId = (Integer) lstPackageAddInTrip.get(i);
            double weightLeft = isReachWeightLimit();
            if (getWeightOfPackage(packageId) < weightLeft) {
                if (isPackageAddToTrip(packageId)) {
                    dictPackageOfTrip.put(packageId, 1);
                } else {
                    dictInvalidPackage.put(packageId, 1);
                }
            } else {
                dictInvalidPackage.put(packageId, 0);
            }
        }
         }catch(Exception npe)
         {
             System.out.println("Cannot load package to trip");
         }
         
        return dictInvalidPackage;
    }

    /**
     * Use to test whether package have suitable destination branch with destination branch of each route in trip
     * @param packageId
     * @return
     */
    public boolean isPackageAddToTrip(int packageId) {
        boolean isAddPackage = false;
        Enumeration<String> routeIds = dictRouteOfTrip.keys();
        while (routeIds.hasMoreElements()) {
            String element=routeIds.nextElement();
            String[] strs =element.split(",");
            int routeId =Integer.parseInt(strs[0]);
            int status = dictRouteOfTrip.get(element);
            if (status != 2) {
                Route r = em.find(Route.class, routeId);
                aptech.eproject.logictics.db.Package p = em.find(aptech.eproject.logictics.db.Package.class, packageId);
             //  System.out.println(r.getToBranch().getBranchId()+"-"+p.getDelivery().getDestinationBranch().getBranchId());
                if (r.getToBranch().getBranchId()==p.getDelivery().getDestinationBranch().getBranchId()) {
                    isAddPackage = true;
                } 
            }
        }
        return isAddPackage;
    }

    /**
     * Use to get message information about invalid package based on status
     * @param lstInvalidPackage
     * @return
     */
    public String getMessage(Dictionary dictInvalidPackage) {
        StringBuffer str = new StringBuffer();
        StringBuffer str0Status =
                new StringBuffer("\n >> Error about weight");
        StringBuffer str1Status =
                new StringBuffer("\n >> Error about invalid destinate branch");
        StringBuffer str2Status =
                new StringBuffer("\n >> Error about package come to destinate branch ");
        StringBuffer str3Status =
                new StringBuffer("\n >> Error about package already at destinate branch ");
                String temp="";
        Enumeration<Integer> packageIds = dictInvalidPackage.keys();
        while (packageIds.hasMoreElements()) {
            Integer packageId = packageIds.nextElement();
            Integer status = (Integer) dictInvalidPackage.get(packageId);
            aptech.eproject.logictics.db.Package p = em.find(aptech.eproject.logictics.db.Package.class, packageId);
            
            if (status == 0) {
                str0Status.append("\nPackage : "+p.getDelivery().getDestinationBranch().getBranchName()+" has invalid weight:"+p.getWeight());
            } else if (status == 1) {
                str1Status.append("\nDestinate Of Package Is invalid : "+p.getDelivery().getDestinationBranch().getBranchName());
            } else if(status == 2) {
                str2Status.append("\nPackage come to destinate : "+p.getDelivery().getDestinationBranch().getBranchName());
            }
            else
            {
                 str3Status.append("\nAlready at destinate :"+p.getDelivery().getDestinationBranch());
            }
        }
        if(!dictInvalidPackage.isEmpty())
        {
            str.append("Please correct following error about package");
            str.append(str0Status.toString());
            str.append(str1Status.toString());
            str.append(str2Status.toString());
            str.append(str3Status.toString());
        }
        return str.toString();
    }

    /**
     * Use to get message information about invalid package based on status
     * @param lstInvalidPackage
     * @return
     */
     public String getMessageHTML(Dictionary dictInvalidPackage) {
         StringBuffer strStatus =
                new StringBuffer("");
          Enumeration<Integer> packageIds = dictInvalidPackage.keys();
          int count=0;
          String branchName="";
            while (packageIds.hasMoreElements()) {
            Integer packageId = packageIds.nextElement();
            Integer status = (Integer) dictInvalidPackage.get(packageId);
            aptech.eproject.logictics.db.Package p = em.find(aptech.eproject.logictics.db.Package.class, packageId);
           if(status == 2) {
              count++;
            }
            branchName=p.getDelivery().getDestinationBranch().getBranchName();
        }
          strStatus.append("There are "+count+" packages come to destinate branch :"+branchName);
          return strStatus.toString();
     }
    /**
     * Remove Trip Information
     * @param tripId - Integer type
     * @return
     *  true : remove successful
     *  false: remove fail : error 
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public boolean removeTrip(int tripId, int branchId) {
        try {
            int wareHouseId;
            Query q;
            // Check to see if It trip have route comming or not
            // Neu co get warehouse ko th`i lay warehouse =  branchId
            try {
                q = em.createQuery("SELECT r FROM Trip t JOIN t.tripRoutes r WHERE r.status = ?1 AND t.tripId = ?2 AND t.isDeleted ='false'");
                q.setParameter(1, TripRouteStatus.Coming);
                q.setParameter(2, tripId);
                TripRoute tr = (TripRoute) q.getSingleResult();
                wareHouseId = tr.getRoute().getFromBranch().getBranchId();
                // Change status comming to arrived
                tr.setStatus(TripRouteStatus.Arrived);
                em.merge(tr);
                
            } catch (NoResultException e) {
                wareHouseId = branchId;
            }

            // Set Information of Vehicle
            Trip trip=em.find(Trip.class, tripId);
                Vehicle v=trip.getVehicle();
                v.setStatus(VehicleStatus.Free);
                em.merge(v);
            // get all package From trip and insert to warehouse 
            q = em.createQuery("SELECT p.packageId FROM TripPackage tp JOIN tp.package p WHERE tp.trip.tripId= ?1");
            q.setParameter(1, tripId);
            List lstPackageFromTrip = q.getResultList();
           // System.out.println("Package size : "+lstPackageFromTrip.size());
            for (int i = 0; i < lstPackageFromTrip.size(); i++) {
                // Insert package to warehouse
                Integer packageId = (Integer) lstPackageFromTrip.get(i);
                //System.out.println("Warehouse : " +branchId  + "Package ID : " + packageId);
                WarehousePK wpk = new WarehousePK(wareHouseId, packageId);
               Warehouse w=em.find(Warehouse.class,wpk);
                if(w!=null)
                {
                    w.setIsRemoved(false);
                    em.merge(w);
                }
                else
                {
                    w = new Warehouse(wpk, false);
                    em.persist(w);
                }
                // Change status of each package in trip IsUnload=true
                //System.out.println("TripId : " + tripId + "Package ID : " + packageId);
                TripPackage tripPackage = em.find(TripPackage.class, new TripPackagePK(packageId,tripId));
                tripPackage.setIsUnloaded(true);
                em.merge(tripPackage);
            }

            // Change status of each route in trip IsDeleted= True
            q = em.createQuery("SELECT t FROM Trip t WHERE t.tripId =?1");
            q.setParameter(1, tripId);
            trip = (Trip) q.getSingleResult();
            Iterator lstTripRoute = trip.getTripRoutes().iterator();
            while (lstTripRoute.hasNext()) {
                Object o = lstTripRoute.next();
                TripRoute tripRoute = (TripRoute) o;
                tripRoute.setIsDeleted(true);
                em.merge(tripRoute);
            }
            // Change status of  trip IsDeleted= True
            trip.setIsDeleted(true);
            em.merge(trip);
            return true;
        } catch (NullPointerException npe) {
            System.err.println("Cannot find entity...");
            npe.printStackTrace();
            context.setRollbackOnly();
            return false;
        } catch (EntityExistsException eee) {
            eee.printStackTrace();
            System.out.println("Package have already in warehouse !!!!");
            context.setRollbackOnly();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            context.setRollbackOnly();
            return false;
        }
    }

    /**
     * Call this method when click remove package from trip
     * Use to remove package out of trip .
     * @param lstPackageFromTrip - List have element type integer
     */
    public void removePackageFromTrip(List<Integer> lstPackageFromTrip) {
        dictPackageOfTrip=getDictPackageOfTrip();
        for (int i = 0; i < lstPackageFromTrip.size(); i++) {

            Integer packageId = lstPackageFromTrip.get(i);
            //System.out.println("Remove Package : "+packageId);
            int status = dictPackageOfTrip.get(packageId);
            if (status != 2) {
                dictPackageOfTrip.put(packageId, 2);
            }
        }
    }

    private short calculateMaxRoute() {
        short totalRoute = 0;
        Enumeration<String> routeIds = dictRouteOfTrip.keys();
        while (routeIds.hasMoreElements()) {
            Integer status = dictRouteOfTrip.get(routeIds.nextElement());
            if (status != 2) {
                totalRoute++;
            }
        }
        return totalRoute;
    }

    /**
     * Call when click add trip button and close dialog .
     * use to add trip information .
     * Use resource from statusful bean addTripService :
     *      vehicleId
     *      dictPackageOfTrip
     *      dictRouteOfTrip
     *      startDate
     * @param startDate
     * @return
     *      true: add trip successful
     *      false: error in insert trip information
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public boolean addTrip(Date startDate) {
        try {
            //System.out.println(vehicleId);
            // Find vehicle
            Vehicle v = em.find(Vehicle.class, vehicleId);
            int branchId=v.getBranch().getBranchId();
            v.setStatus(VehicleStatus.Working);
            em.merge(v);
            // Persist Trip
            Trip trip = new Trip();
            trip.setVehicle(v);
            trip.setStartDate(new java.sql.Timestamp(startDate.getTime()));
            trip.setMaxRoute(calculateMaxRoute());
            em.persist(trip);

            //Find exist trip
            int tripId = trip.getTripId();
           // System.out.println("Trip generated : "+tripId);
            //Set Package Of Trip information
            Enumeration<Integer> packageIds = dictPackageOfTrip.keys();
            Set<TripPackage> packages=new HashSet<TripPackage>();
           // System.out.println("The package of trip: ");
            while (packageIds.hasMoreElements()) {
                Integer packageId = packageIds.nextElement();
                int status = dictPackageOfTrip.get(packageId);
                
                if (status != 2) {
                    //Remove Package From Warehouse
                    WarehousePK wpk=new WarehousePK(branchId,packageId);
                   Warehouse w=em.find(Warehouse.class, wpk);
                   w.setIsRemoved(true);
                   em.merge(w);
                   // Change status of package
                   aptech.eproject.logictics.db.Package p=em.find(aptech.eproject.logictics.db.Package.class,packageId);
                   p.setDeliveryStatus(DeliveryStatus.Consigning);
                   em.merge(p);
                    // Load Package To Trip
                    TripPackage tripPackage = new TripPackage(new TripPackagePK(packageId.intValue(), tripId), false);
                    tripPackage.setTrip(trip);
                    packages.add(tripPackage);
                }
            }
          //  System.out.println("The route of trip: ");
            Set<TripRoute> routes=new HashSet<TripRoute>();
            //Set Route Of Trip information
            Enumeration<String> routeIds = dictRouteOfTrip.keys();
          
            routeIds = dictRouteOfTrip.keys();

            //get Total Route have status is !2

            while (routeIds.hasMoreElements()) {
                String element=routeIds.nextElement();
                String[] strs= element.split(",");
                int routeId = Integer.parseInt(strs[0]);
                int order=Integer.parseInt(strs[1]);
                int status = dictRouteOfTrip.get(element);
                if (status != 2) {
                    TripRoute tripRoute 
                            = new TripRoute(new TripRoutePK(routeId, tripId), false, TripRouteStatus.Planned);
                    if(order==1)
                    {
                        tripRoute.setStatus(TripRouteStatus.Coming);
                    }
                    tripRoute.setRouteOrder((short) order);
                    tripRoute.setTrip(trip);
                    routes.add(tripRoute);
                }
            }
            trip.setTripRoutes(routes);
            trip.setTripPackages(packages);
          
            // Merge Trip
            trip=em.merge(trip);
            cancelTripService();
            return true;
        } catch (NullPointerException npe) {
            System.err.println("Not have enough information to process add trip operation!!!");
            context.setRollbackOnly();
            npe.printStackTrace();
            return false;
        } catch (EntityExistsException eee) {
            System.err.println("Entity have already existed");
            context.setRollbackOnly();
            return false;
        } catch (Exception e) {
            System.err.println("Error In insert trip information : " + e.getMessage());
            e.printStackTrace();
            context.setRollbackOnly();
            return false;
        }
    }

    public Dictionary<String, Integer> getDictRouteOfTrip() {
        return dictRouteOfTrip;
    }

    public Dictionary<Integer, Integer> getDictPackageOfTrip() {
        return dictPackageOfTrip;
    }

    /**
   * get Information about all package in warehouse based on paramter branchId
   * @param branchId
   * @return
   *    List of element type Package
   */
  public List listPackageInWarehouse(int branchId)
  {
      try {
         Query query=em.createQuery("SELECT p FROM Warehouse w JOIN w.package p WHERE w.branch.branchId= ?1 AND w.isRemoved='False'");
         query.setParameter(1, branchId);
        return query.getResultList();
      }
      catch(NullPointerException npe)
      {
          System.err.println("Cannot find information about query !!!");
          return null;
      }
      catch (Exception e) {
          e.printStackTrace();
          return null;
      }
  }

  /**
   * init the package already in trip.
   * get list of package in trip
   * @param tripId - Integer type
   * @return
   *    list pacakge Id each element type integer
   */
  public List listPackageInTrip(int tripId)
  {
      try {
          // Get list package Id of trip
          Query q= em.createQuery("SELECT tp.package FROM TripPackage tp WHERE tp.trip.tripId= ?1 AND tp.isUnloaded='False'");
          q.setParameter(1,tripId);
          List packageIds=q.getResultList();
         // initTripService();
          for (int i = 0; i < packageIds.size(); i++) {
               aptech.eproject.logictics.db.Package p = ( aptech.eproject.logictics.db.Package)packageIds.get(i);
              dictPackageOfTrip.put(p.getPackageId(), 0);
          }
          return packageIds;
      }
      catch(NullPointerException npe)
      {
          System.err.println("Cannot find information about query !!!");
          return null;
      }
      catch (Exception e) {
          e.printStackTrace();
          return null;
      }
  }

 /**
  * get branch based on branch id
  * @param branchId
  * @return
  */
  public Branch getBranch(int branchId)
  {
      return em.find(Branch.class, branchId);
  }

   /**
     * getList Trip Route Sort based On RouteOrder
     */
    public  List lstTripRouteASC(int tripId)
    {
        try {
           Query q=em.createQuery("SELECT tr FROM TripRoute tr WHERE tr.trip.tripId =?1 ORDER BY tr.routeOrder ASC");
           q.setParameter(1, tripId);
            return q.getResultList();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
